package com.fire.market.service.impl.impl;

import com.fire.component.cache.local.RedisOperate;
import com.fire.component.extension.Assert;
import com.fire.component.extension.BizCommonError;
import com.fire.component.extension.ExceptionFactory;

import com.fire.market.manager.ItemManager;
import com.fire.market.model.ItemModel;
import com.fire.market.mq.producer.ItemStockProducerManager;
import com.fire.market.product.api.dto.ItemInfo;
import com.fire.market.product.api.mq.ItemStockMqMessage;
import com.fire.market.product.api.request.ItemAddParam;
import com.fire.market.product.api.request.ItemDecreaseParam;
import com.fire.market.product.api.result.ItemStockDecreaseResult;
import com.fire.market.service.impl.ItemCmdCoreService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
public class ItemCmdCoreServiceImpl implements ItemCmdCoreService {
    @Resource
    private ItemManager itemManager;

    @Resource
    private RedisTemplate<Object, Object> redisTemplate;

    @Resource
    private ItemStockProducerManager itemStockProducerManager;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ItemInfo createItem(ItemAddParam param) {
        Assert.notNull(param, "ItemInfo is null");
        //保存商品项
        ItemModel itemModel = new ItemModel();
        BeanUtils.copyProperties(param, itemModel);
        itemModel.setPrice(param.getPrice());
        return itemManager.createItem(itemModel);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ItemStockDecreaseResult decreaseItemStock(ItemDecreaseParam param) {
        Assert.notNull(param, "ItemDecreaseParam is null");
        boolean res = itemManager.decreaseStock(param.getItemId(), param.getAmount());
        ItemStockDecreaseResult itemStockDecreaseResult = new ItemStockDecreaseResult();
        itemStockDecreaseResult.setStatus(res);
        return itemStockDecreaseResult;
    }

    @Override
    public ItemStockDecreaseResult decreaseItemStockByCache(ItemDecreaseParam param) {
        //校验库存是否售空
        if (RedisOperate.hasKey("promo_item_stock_invalid_" + param.getItemId())) {
            throw ExceptionFactory.bizException(BizCommonError.STOCK_NOT_ENOUGH.getErrCode(),
                    BizCommonError.STOCK_NOT_ENOUGH.getErrMsg());
        }
        long result = RedisOperate.incr("promo_item_stock_" + param.getItemId(), param.getAmount() * -1);
        ItemStockDecreaseResult itemStockDecreaseResult = new ItemStockDecreaseResult();
        if (result > 0) {
            itemStockDecreaseResult.setStatus(true);
        } else if (result == 0) {
            //通知库存售完
            RedisOperate.set("promo_item_stock_invalid_" + param.getItemId(), "true");
        } else {
            itemStockDecreaseResult.setStatus(false);
        }
        return itemStockDecreaseResult;
    }


    @Override
    public void increaseItemStockByCache(ItemDecreaseParam param) {
        RedisOperate.incr("promo_item_stock_" + param.getItemId(), param.getAmount());
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void increaseSales(Integer itemId, Integer amount) {
        Assert.notNull(itemId, "itemId is null");
        Assert.notNull(amount, "amount is null");
        itemManager.increaseSales(itemId, amount);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void decreaseSales(Integer itemId, Integer amount) {
        Assert.notNull(itemId, "itemId is null");
        Assert.notNull(amount, "amount is null");
        itemManager.decreaseSales(itemId, amount);
    }

    @Override
    public void syncDecreaseItemStockByMq(ItemStockMqMessage itemStockMqMessage) {
        itemStockProducerManager.sendItemStockMsg(itemStockMqMessage);
    }

}
